xen/arm: gic: split set_irq_properties
authorJulien Grall <julien.grall@arm.com>
Wed, 27 Jul 2016 13:58:24 +0000 (14:58 +0100)
committerStefano Stabellini <sstabellini@kernel.org>
Wed, 27 Jul 2016 19:23:21 +0000 (12:23 -0700)
The callback set_irq_properties will configure the GIC for a specific
IRQ with the type and the priority.

In a follow-up patch, Xen will configure the type and the priority at
different stage of the routing. So split it in 2 separate callbacks.

At the same time, move the ASSERT to check the validity of the type and
if the desc->lock is locked in the common code (gic.c). This is because
the constraint are the same between GICv2 and GICv3, however the driver
of the latter did not contain any sanity check.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/gic-v2.c
xen/arch/arm/gic-v3.c
xen/arch/arm/gic.c
xen/include/asm-arm/gic.h

index 6c7dbfee903c082eda62653b6d8cb2f08a4d59d0..69ed72d29fe6ca6c9bb7729f45b2b33b94de95b9 100644 (file)
@@ -236,16 +236,12 @@ static unsigned int gicv2_read_irq(void)
     return (readl_gicc(GICC_IAR) & GICC_IA_IRQ);
 }
 
-static void gicv2_set_irq_properties(struct irq_desc *desc,
-                                     unsigned int priority)
+static void gicv2_set_irq_type(struct irq_desc *desc)
 {
     uint32_t cfg, actual, edgebit;
     unsigned int irq = desc->irq;
     unsigned int type = desc->arch.type;
 
-    ASSERT(type != IRQ_TYPE_INVALID);
-    ASSERT(spin_is_locked(&desc->lock));
-
     spin_lock(&gicv2.lock);
     /* Set edge / level */
     cfg = readl_gicd(GICD_ICFGR + (irq / 16) * 4);
@@ -270,6 +266,16 @@ static void gicv2_set_irq_properties(struct irq_desc *desc,
             IRQ_TYPE_LEVEL_HIGH;
     }
 
+    spin_unlock(&gicv2.lock);
+}
+
+static void gicv2_set_irq_priority(struct irq_desc *desc,
+                                   unsigned int priority)
+{
+    unsigned int irq = desc->irq;
+
+    spin_lock(&gicv2.lock);
+
     /* Set priority */
     writeb_gicd(priority, GICD_IPRIORITYR + irq);
 
@@ -1217,7 +1223,8 @@ const static struct gic_hw_operations gicv2_ops = {
     .eoi_irq             = gicv2_eoi_irq,
     .deactivate_irq      = gicv2_dir_irq,
     .read_irq            = gicv2_read_irq,
-    .set_irq_properties  = gicv2_set_irq_properties,
+    .set_irq_type        = gicv2_set_irq_type,
+    .set_irq_priority    = gicv2_set_irq_priority,
     .send_SGI            = gicv2_send_SGI,
     .disable_interface   = gicv2_disable_interface,
     .update_lr           = gicv2_update_lr,
index d6ab0e9bd85e04139e03a86f89a8eb1029078c6c..781f25c2e4d53e30f8e01f06b7876b0960c57c73 100644 (file)
@@ -471,8 +471,7 @@ static inline uint64_t gicv3_mpidr_to_affinity(int cpu)
              MPIDR_AFFINITY_LEVEL(mpidr, 0));
 }
 
-static void gicv3_set_irq_properties(struct irq_desc *desc,
-                                     unsigned int priority)
+static void gicv3_set_irq_type(struct irq_desc *desc)
 {
     uint32_t cfg, actual, edgebit;
     void __iomem *base;
@@ -512,6 +511,15 @@ static void gicv3_set_irq_properties(struct irq_desc *desc,
             IRQ_TYPE_EDGE_RISING :
             IRQ_TYPE_LEVEL_HIGH;
     }
+    spin_unlock(&gicv3.lock);
+}
+
+static void gicv3_set_irq_priority(struct irq_desc *desc,
+                                   unsigned int priority)
+{
+    unsigned int irq = desc->irq;
+
+    spin_lock(&gicv3.lock);
 
     /* Set priority */
     if ( irq < NR_GIC_LOCAL_IRQS )
@@ -1579,7 +1587,8 @@ static const struct gic_hw_operations gicv3_ops = {
     .eoi_irq             = gicv3_eoi_irq,
     .deactivate_irq      = gicv3_dir_irq,
     .read_irq            = gicv3_read_irq,
-    .set_irq_properties  = gicv3_set_irq_properties,
+    .set_irq_type        = gicv3_set_irq_type,
+    .set_irq_priority    = gicv3_set_irq_priority,
     .send_SGI            = gicv3_send_sgi,
     .disable_interface   = gicv3_disable_interface,
     .update_lr           = gicv3_update_lr,
index bc814a000220cdd788b860a298cc71b1de22f955..c63c8626a81595f2ad6bddb90503623512d078ea 100644 (file)
@@ -96,14 +96,17 @@ void gic_restore_state(struct vcpu *v)
     gic_restore_pending_irqs(v);
 }
 
-/*
- * - desc.lock must be held
- * - arch.type must be valid (i.e != IRQ_TYPE_INVALID)
- */
-static void gic_set_irq_properties(struct irq_desc *desc,
-                                   unsigned int priority)
+static void gic_set_irq_type(struct irq_desc *desc)
+{
+    ASSERT(spin_is_locked(&desc->lock));
+    ASSERT(desc->arch.type != IRQ_TYPE_INVALID);
+
+    gic_hw_ops->set_irq_type(desc);
+}
+
+static void gic_set_irq_priority(struct irq_desc *desc, unsigned int priority)
 {
-    gic_hw_ops->set_irq_properties(desc, priority);
+    gic_hw_ops->set_irq_priority(desc, priority);
 }
 
 /* Program the GIC to route an interrupt to the host (i.e. Xen)
@@ -118,7 +121,8 @@ void gic_route_irq_to_xen(struct irq_desc *desc, unsigned int priority)
 
     desc->handler = gic_hw_ops->gic_host_irq_type;
 
-    gic_set_irq_properties(desc, priority);
+    gic_set_irq_type(desc);
+    gic_set_irq_priority(desc, priority);
 }
 
 /* Program the GIC to route an interrupt to a guest
@@ -150,7 +154,8 @@ int gic_route_irq_to_guest(struct domain *d, unsigned int virq,
     desc->handler = gic_hw_ops->gic_guest_irq_type;
     set_bit(_IRQ_GUEST, &desc->status);
 
-    gic_set_irq_properties(desc, priority);
+    gic_set_irq_type(desc);
+    gic_set_irq_priority(desc, priority);
 
     p->desc = desc;
     res = 0;
index 7ba384664c070689f6067f1fc62b8b9fcc6b5530..3f39f7973ec68b546d930f4f47921f38d4a13843 100644 (file)
@@ -328,9 +328,10 @@ struct gic_hw_operations {
     void (*deactivate_irq)(struct irq_desc *irqd);
     /* Read IRQ id and Ack */
     unsigned int (*read_irq)(void);
-    /* Set IRQ property */
-    void (*set_irq_properties)(struct irq_desc *desc,
-                               unsigned int priority);
+    /* Set IRQ type - type is taken from desc->arch.type */
+    void (*set_irq_type)(struct irq_desc *desc);
+    /* Set IRQ priority */
+    void (*set_irq_priority)(struct irq_desc *desc, unsigned int priority);
     /* Send SGI */
     void (*send_SGI)(enum gic_sgi sgi, enum gic_sgi_mode irqmode,
                      const cpumask_t *online_mask);